package com.hzsk.lisence.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hzsk.lisence.config.AnnotationForLog;
import com.hzsk.lisence.config.MyConfig;
import com.hzsk.lisence.config.myexception.OperateException;
import com.hzsk.lisence.config.myexception.ParameterException;
import com.hzsk.lisence.entity.*;
import com.hzsk.lisence.entity.query.LisenceServiceQuery;
import com.hzsk.lisence.entity.response.IncResponce;
import com.hzsk.lisence.entity.response.LisenceData;
import com.hzsk.lisence.mapper.HardwareMapper;
import com.hzsk.lisence.mapper.LisenceUserMapper;
import com.hzsk.lisence.mapper.SoftwareLicenseMapper;
import com.hzsk.lisence.mapper.SoftwareSonMapper;
import com.hzsk.lisence.service.SoftwareLicenseService;
import com.hzsk.lisence.util.JsonUtils;
import com.hzsk.lisence.util.JwtUtils;
import com.hzsk.lisence.util.RsaUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.ResourceUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
public class SoftwareLicenseServiceImpl implements SoftwareLicenseService {


    @Resource
    public SoftwareLicenseMapper softwareLicenseMapper;
    @Resource
    public LisenceUserMapper lisenceUserMapper;
    @Resource
    public HardwareMapper hardwareMapper;
    @Resource
    public SoftwareSonMapper softwareSonMapper;


    @Override
    @AnnotationForLog(operationType = LogEnum.SAVE_LISENCE,operation = "保存许可",operationalEntity = "SoftwareLicenseEntity.java/STUDENT_T")
    public String saveSoftwareLicense(SoftwareLicenseEntity softwareLicenseEntity,Integer userId) {
        softwareLicenseMapper.saveSoftwareLicense(softwareLicenseEntity);
        Integer softwareId = softwareLicenseEntity.getSoftwareId();
        Integer id = softwareLicenseEntity.getId();
        String hardwareKey = softwareLicenseEntity.getHardwareKey();
        String[] split = hardwareKey.split(";");
        for (String key : split) {
            List<HardwareEntity> hardwareEntities = hardwareMapper.selectHardwareNameByKey(key);
            HardwareConnSoftware hardwareConnSoftware = new HardwareConnSoftware();
            hardwareConnSoftware.setSoftwareId(softwareId);
            hardwareConnSoftware.setHardwareId(hardwareEntities.get(0).getId());
            hardwareMapper.saveConnSoftware(hardwareConnSoftware);
        }
        List<SoftwareSonEntity> softwareSons = softwareLicenseEntity.getSoftwareSons();
        for (SoftwareSonEntity softwareSon : softwareSons) {
            softwareSon.setSaveType(2);
            softwareSon.setSoftwareId(softwareId);
            softwareSon.setLisenceId(id);
            softwareSon.setSourseId(softwareSon.getId());
            softwareSonMapper.saveSoftwareSonInfo(softwareSon);
        }
        return "操作成功";
    }

    @Override
    @AnnotationForLog(operationType = LogEnum.PUBLISH,operation = "license发布",operationalEntity = "SoftwareLicenseEntity.java/STUDENT_T")
    public InputStream publishSoftwareLicense(Integer id, Integer userId) throws Exception {
        Path tempDir = Files.createTempDirectory("lisenceZip");
        Path zipFilePath = tempDir.resolve("lisence.zip");
        FileOutputStream fos = new FileOutputStream(zipFilePath.toFile());
        ZipOutputStream zos = new ZipOutputStream(fos);
        try {
            SoftwareLicenseEntity softwareLicenseEntity = softwareLicenseMapper.selectAllById(id);
            if (softwareLicenseEntity != null) {
                String hardwareKey = softwareLicenseEntity.getHardwareKey();
                if (StringUtils.isBlank(hardwareKey)) throw new OperateException("无硬件信息");
                String[] split = hardwareKey.split(";");
                Integer groupId = lisenceUserMapper.getUserGroupId(userId);
                String groupType = lisenceUserMapper.getGroupType(groupId);
                Integer softwareId = softwareLicenseEntity.getSoftwareId();
                List<SoftwareSonEntity> softwareListSonInfo = softwareSonMapper.getSoftwareListSonInfo(softwareLicenseEntity.getId(),softwareId, 2);
                //工业互联网
                if(groupType.equals(UserRole.HZSK.toString())) {
                    for (String key : split) {
                        List<HardwareEntity> hardwareEntities = hardwareMapper.selectHardwareNameByKey(key);
                        String name = hardwareEntities.get(0).getHardwareName();
                        if (StringUtils.isBlank(name)) throw new OperateException("参数异常");
                        //数控lisence加密逻辑
                        softwareLicenseEntity.setHardwareKey(key);
                        softwareLicenseEntity.setSoftwareSons(softwareListSonInfo);
                        String string = JsonUtils.toString(softwareLicenseEntity);
                        PrivateKey privateKey = RsaUtils.getPrivateKey(ResourceUtils.getFile(MyConfig.PRI).getPath());
                        String content = JwtUtils.generateKey(string, privateKey);
                        JSONObject res = new JSONObject();
                        res.put("A",content);
                        String publicKeyString = RsaUtils.getPublicKeyString(ResourceUtils.getFile(MyConfig.PUB).getPath());
                        res.put("B",publicKeyString);
                        // Create files
                        Path file = tempDir.resolve(name+".lisence");
                        Files.write(file, res.toString().getBytes());
                        addToZipFile(file.toFile(), zos);
                    }
                    //数控中心lisence加密逻辑
                }else if (groupType.equals(UserRole.CNC_CENTER.toString())) {

                }else{
                    throw new ParameterException("请求参数异常");
                }
                zos.finish();
                byte[] zipFileContent = Files.readAllBytes(zipFilePath);
                // Return zip file as a Resource
                ByteArrayResource byteArrayResource = new ByteArrayResource(zipFileContent);
                return byteArrayResource.getInputStream();

            }else throw new ParameterException("请求参数异常");
        } finally {
            zos.finish();
        }
    }

    @Override
    @AnnotationForLog(operationType = LogEnum.PUBLISH,operation = "license发布根据JSON",operationalEntity = "SoftwareLicenseEntity.java/STUDENT_T")
    public String publishSoftwareLicenseByJson(Integer userId,JSONObject data) throws Exception {
        return JwtUtils.generateKey(data.toJSONString(),RsaUtils.getPrivateKey(ResourceUtils.getFile(MyConfig.PRI).getPath()));
    }

    @Override
    public SoftwareLicenseEntity getsoftwarelicenseById(Integer id) {
        SoftwareLicenseEntity softwareLicenseEntity = softwareLicenseMapper.selectAllById(id);
        if (softwareLicenseEntity != null) {
            Integer softwareId = softwareLicenseEntity.getSoftwareId();
            List<SoftwareSonEntity> softwareListSonInfo = softwareSonMapper.getSoftwareListSonInfo(id,softwareId, 2);
            softwareLicenseEntity.setSoftwareSons(softwareListSonInfo);
        }
        return softwareLicenseEntity;
    }

    @Override
    public Object getSoftwareLicenseByUserId(LisenceServiceQuery lisenceServiceQuery) {
        PageHelper.startPage(lisenceServiceQuery.getPageNum(), lisenceServiceQuery.getPageSize());
        List<LisenceData> infos = softwareLicenseMapper.getSoftwareLicenseByUserId(lisenceServiceQuery);
        for (LisenceData info : infos) {
            Integer userId = info.getUserId();
            String userName = lisenceUserMapper.getUserNameById(userId);
            info.setUserName(userName);
        }
        return new PageInfo<>(infos);
    }

    @Override
    @AnnotationForLog(operationType = LogEnum.UPDATE_LISENCE,operation = "修改许可",operationalEntity = "SoftwareLicenseEntity.java/STUDENT_T")
    public String updateSoftwareLicense(SoftwareLicenseEntity softwareLicenseEntity,Integer userId) {
        softwareLicenseMapper.updateSoftwareLicense(softwareLicenseEntity);
        return "操作成功";
    }

    @Override
    @AnnotationForLog(operationType = LogEnum.DEL_LISENCE,operation = "删除许可",operationalEntity = "SoftwareLicenseEntity.java/STUDENT_T")
    public String delSoftwareLicense(Integer id,Integer userId) {
        softwareLicenseMapper.delSoftwareLicense(id);
        return "操作成功";
    }

    @Override
    @AnnotationForLog(operationType = LogEnum.CONFIRM_LISENCE,operation = "确认许可",operationalEntity = "SoftwareLicenseEntity.java/STUDENT_T")
    public String confirmSoftwareLicense(Integer id,Integer userId) {
        softwareLicenseMapper.confirmSoftwareLicense(id);
        return "操作成功";
    }



    private static void addToZipFile(File file, ZipOutputStream zos) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        ZipEntry zipEntry = new ZipEntry(file.getName());
        zos.putNextEntry(zipEntry);
        byte[] bytes = new byte[1024];
        int length;
        while ((length = fis.read(bytes)) >= 0) {
            zos.write(bytes, 0, length);
        }
        zos.closeEntry();
        fis.close();
    }

}
